package edu.taru.office.controller;

import edu.taru.office.common.Constants;
import edu.taru.office.common.JsonResult;
import edu.taru.office.common.SessionUser;

import edu.taru.office.service.ProcessService;
import edu.taru.office.util.StringUtil;
import edu.taru.office.util.UserUtil;
import edu.taru.office.vo.MyApply;
import edu.taru.office.vo.MyTask;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;

import org.activiti.image.impl.DefaultProcessDiagramGenerator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;

import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.*;

/**
 * 通用的流程的操作 包含部署、待办、我的任务
 */
@Controller
public class ProcessController {

    private Logger logger= LoggerFactory.getLogger(ProcessController.class);
    //注入为我们自动配置好的服务
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService  repositoryService;

    @Autowired
    private ProcessService processService;


    @Autowired
    private HistoryService historyService;

    /**
     * 部署某流程（测试案例）
     * @return
     */
    @RequestMapping("/process/deploy")
    @ResponseBody
    public Object  deploy(  @RequestParam ("filename") String filename){
        JsonResult<String> result = null;
        System.out.println(filename+"***************");
        if (filename !=null && filename.length() != 0){
            try {
                repositoryService.createDeployment().addClasspathResource(filename).deploy();
                result = new JsonResult<String>(Constants.STATUS_OK,"流程部署成功");
            }catch (Exception e){
                result = new JsonResult<String>(Constants.STATUS_ERROR,"部署流程异常",e.getMessage());
            }
        }else {
                result = new JsonResult<String>(Constants.STATUS_NO_DATA,"流程不存在请重新部署");
        }
        return result;
    }


    /**
     * 查看流程图
     * @param definitionId
     * @param executionId
     * @param response
     * @throws Exception
     */
    @RequestMapping("/process/diagram")
    public void  qryDiagram( @RequestParam ("processDefinitionId") String definitionId,
                            @RequestParam ("proid") String executionId,
                              HttpServletResponse response)throws Exception{

        InputStream imageStream = null;
        BpmnModel bpmnModel = repositoryService.getBpmnModel(definitionId);
        List<String> activeActivityIds = runtimeService.getActiveActivityIds(executionId);

        imageStream =  new DefaultProcessDiagramGenerator().generateDiagram(bpmnModel, "png", activeActivityIds, Collections.<String>emptyList(), "宋体", "宋体", "宋体", null, 1.0);

        response.setHeader("Cache-Control", "no-store");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");

        byte[] b = new byte[1024];
        int len; while ((len = imageStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }

        response.getOutputStream().flush();
        response.getOutputStream().close();


    }





    /**
     * 待办任务
     * @param model
     * @param session
     * @return
     */
    @RequestMapping("/process/dolist")
    public String  dolist(Model model , HttpSession session){
        List<Task> tasks=null;
        List<MyTask>  myTasks =new ArrayList<MyTask>();
        //获取当前用户的角色
        SessionUser  sessionUser=(SessionUser)session.getAttribute(Constants.LOGIN_USER_KEY);
        if(sessionUser!=null){
            String id =sessionUser.getUserid();
            //根据Id查询角色
            List<String>  list =processService.selectRoleIds(id);

            tasks = taskService.createTaskQuery().taskCandidateGroupIn(list).orderByTaskCreateTime().desc().list();
            if(tasks.size()>0){
                for (Task task : tasks) {
                    String processInstanceId = task.getProcessInstanceId();

                    ProcessInstance pi = runtimeService.createProcessInstanceQuery().includeProcessVariables().processInstanceId(processInstanceId).singleResult();
                    String businessKey = pi.getBusinessKey();
                    String  category =String.valueOf(pi.getProcessVariables().get(Constants.Process.CATEGORY));
                    String  title =String.valueOf(pi.getProcessVariables().get(Constants.Process.TITLE));
                    String  owner =String.valueOf(pi.getProcessVariables().get(Constants.Process.OWNER));
                    logger.info("----------------------processInstanceId si {}",pi.getId());
                    logger.info("----------------------businessKey si {}",businessKey);
                    logger.info("----------------------category si {}",category);
                    logger.info("----------------------title si {}",title);
                    logger.info("----------------------owner si {}",owner);
                    MyTask myTask =new MyTask();
                    myTask.setTaskId(task.getId());
                    myTask.setCreateDate(task.getCreateTime());
                    myTask.setOwner(owner);
                    myTask.setCategory(category);
                    myTask.setTitle(title);
                    myTask.setBusinessKey(businessKey);
                    myTasks.add(myTask);

                }
            }
            model.addAttribute("dolist",myTasks);

        }
        return  "process/dolist";


    }



    /**
     * 我（当前用户）提交的历史审批，包含活动中的和已经审批完成的
     * @param model
     * @param session
     * @return
     */
    @RequestMapping("/process/applys")
    public String  qryApplys(Model model , HttpSession session){
        String userId = UserUtil.getSessionUserFromSession(session).getUserid();
        HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery();
        List<HistoricProcessInstance>   processInstances = query.includeProcessVariables().startedBy(userId).orderByProcessInstanceStartTime().desc().list();
        List<MyApply>  myApplys =new ArrayList<>();
        if(processInstances!=null &&processInstances.size()>0 ){
                for(HistoricProcessInstance hp:processInstances){
                    MyApply myApply =new MyApply();
                    myApply.setBusinessKey(hp.getBusinessKey());
                    myApply.setProcessId(hp.getId());
                    Map<String, Object> variables =hp.getProcessVariables();
                    myApply.setCategory(StringUtil.toNullOrString(variables.get(Constants.Process.CATEGORY)));
                    myApply.setTitle(StringUtil.toNullOrString(variables.get(Constants.Process.TITLE)));
                    myApply.setCreateDate(hp.getStartTime());
                    myApply.setProcessDefinitionName(hp.getProcessDefinitionName());
                    myApply.setProcessDefinitionKey(hp.getProcessDefinitionKey());
                    myApply.setProcessDefinitionId(hp.getProcessDefinitionId());
                    myApplys.add(myApply);


                }
        }
        model.addAttribute("applys",myApplys);

        return  "process/applys";
    }



    /**
     * 我（当前用户）在活动中的审批，没有审批完毕的
     * @param model
     * @param session
     * @return
     */
    @RequestMapping("/process/unfinished")
    public String  qryHistorys(Model model , HttpSession session){

        String userId = UserUtil.getSessionUserFromSession(session).getUserid();
        HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery();
        List<HistoricProcessInstance>   processInstances = query.includeProcessVariables().
                startedBy(userId).orderByProcessInstanceStartTime().desc().unfinished().list();
        List<MyApply>  myApplys =new ArrayList<>();
        if(processInstances!=null &&processInstances.size()>0 ){
            for(HistoricProcessInstance hp:processInstances){
                MyApply myApply =new MyApply();
                myApply.setBusinessKey(hp.getBusinessKey());
                myApply.setProcessId(hp.getId());
                Map<String, Object> variables =hp.getProcessVariables();
                myApply.setCategory(StringUtil.toNullOrString(variables.get(Constants.Process.CATEGORY)));
                myApply.setTitle(StringUtil.toNullOrString(variables.get(Constants.Process.TITLE)));
                myApply.setCreateDate(hp.getStartTime());
                myApply.setProcessDefinitionName(hp.getProcessDefinitionName());
                myApply.setProcessDefinitionKey(hp.getProcessDefinitionKey());
                myApply.setProcessDefinitionId(hp.getProcessDefinitionId());
                myApplys.add(myApply);


            }
        }
        model.addAttribute("applys",myApplys);
        return  "process/unfinished";
    }



    /**
     * 查询流程定义列表
     * @param model
     * @return
     */
    @RequestMapping("/process/list")
    public  String qyrList(Model model){
        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()//创建一个流程定义查询
                        /*指定查询条件,where条件*/
                //.deploymentId(deploymentId)//使用部署对象ID查询
                //.processDefinitionId(processDefinitionId)//使用流程定义ID查询
                //.processDefinitionKey(processDefinitionKey)//使用流程定义的KEY查询
                //.processDefinitionNameLike(processDefinitionNameLike)//使用流程定义的名称模糊查询

                        /*排序*/
                .orderByProcessDefinitionVersion().asc()//按照版本按照流程定义的名称降序排列的升序排列
                //.orderByProcessDefinitionName().desc()//

                .list();//返回一个集合列表，封装流程定义
        //.singleResult();//返回唯一结果集
        //.count();//返回结果集数量
        //.listPage(firstResult, maxResults)//分页查询
        model.addAttribute("list",list);
        return "process/define";
    }

}
